package ws

import (
	"errors"
	"log"
	"net"
	"strings"
)

type WsSocket struct {
	MaskingKey []byte
	Conn       net.Conn
}

func NewWsSocket(conn net.Conn) *WsSocket {
	return &WsSocket{Conn: conn}
}

func (_this *WsSocket) SendIframe(data []byte) error {
	// 这里只处理data长度<125的
	if len(data) >= 125 {
		return errors.New("send iframe data error")
	}

	lenth := len(data)
	maskedData := make([]byte, lenth)
	// 进行掩码运算
	for i := 0; i < lenth; i++ {
		if _this.MaskingKey != nil {
			maskedData[i] = data[i] ^ _this.MaskingKey[i%4]
		} else {
			maskedData[i] = data[i]
		}
	}

	// 0x81 这应该是个魔数(10000001)
	_this.Conn.Write([]byte{0x81})

	var payLenByte byte
	if _this.MaskingKey != nil && len(_this.MaskingKey) != 4 {
		payLenByte = byte(0x80) | byte(lenth)
		_this.Conn.Write([]byte{payLenByte})
		_this.Conn.Write(_this.MaskingKey)
	} else {
		payLenByte = byte(0x00) | byte(lenth)
		_this.Conn.Write([]byte{payLenByte})
	}
	_this.Conn.Write(data)
	return nil
}

func (current *WsSocket) ReadIframe() (data []byte, err error) {

	// 第一字节 FIN+RSV-3+OPCODE
	opcodeByte := make([]byte, 1)
	current.Conn.Read(opcodeByte)

	FIN := opcodeByte[0] >> 7
	RSV1 := opcodeByte[0] >> 6 & 1
	RSV2 := opcodeByte[0] >> 5 & 1
	RSV3 := opcodeByte[0] >> 4 & 1

	// FIN + RSV-3 占用4个字节， 剩余就是OPCODE, 与15(1111)进行与运算计划出opcode
	OPCODE := opcodeByte[0] & 15 // 15的1进制：1111
	log.Println(FIN, RSV1, RSV2, RSV3, OPCODE)

	// 第二个字节：读取payload长度, 这个字节最高位是：mask值
	payloadLenByte := make([]byte, 1)
	current.Conn.Read(payloadLenByte)

	log.Println("payload bytes", payloadLenByte[0])

	// 需要与0x7F(01111111)进行与运算, 最高位设置为0后，转换为int
	payloadLen := int(payloadLenByte[0] & 0x7F)
	log.Println("payload length", payloadLen)

	// payload所在字节最高位是mask值
	mask := payloadLenByte[0] >> 7
	log.Println("mask", mask)

	// 如果payload长度==1byte(127)
	if payloadLen == 127 {
		extendByte := make([]byte, 8)
		current.Conn.Read(extendByte)
		log.Println("读取extend数据")
	}

	// mask 4个字节
	maskingByte := make([]byte, 4)
	if mask == 1 {
		current.Conn.Read(maskingByte)
		current.MaskingKey = maskingByte
		log.Println("读取maskingByte", maskingByte)
	}

	// 读取payload数据
	payloadDataByte := make([]byte, payloadLen)
	current.Conn.Read(payloadDataByte)
	log.Println("data", payloadDataByte)

	dataByte := make([]byte, payloadLen)
	for i := 0; i < payloadLen; i++ {
		if mask == 1 {
			dataByte[i] = payloadDataByte[i] ^ maskingByte[i%4]
		} else {
			dataByte[i] = payloadDataByte[i]
		}
	}

	// 如果FIN=1, 表示数据读取完成
	if FIN == 1 {
		data = dataByte
		return
	}

	// 否则递归读取后续数据
	nextData, err := current.ReadIframe()
	if err != nil {
		return
	}
	data = append(data, nextData...)
	log.Println("data", string(data))
	return
}

func parseHandsanke(r string) map[string]string {
	lines := strings.Split(r, "\r\n")
	headers := make(map[string]string, 10)
	for _, line := range lines {
		if len(line) > 0 {
			metaData := strings.Split(line, ":")
			if len(metaData) == 2 {
				headers[strings.Trim(metaData[0], " ")] = strings.Trim(metaData[1], " ")
			}
		}
	}
	return headers
}
